
export interface IDItem {
    destroyed: boolean;
}
export abstract class DItem implements IDItem {
    destroyed: boolean = false;
}
export class DList<T extends IDItem> extends Array<IDItem>{
    /**
     * 标记有物体被移除
     */
    m_RemoveDirty: boolean = false;
    /**
     * 标记有物体延迟添加
     */
    m_AddDirty: boolean = false;
    /**
     * 延迟添加物体的等待列表
     */
    delayAddList: Array<T> = new Array<T>();

    DelayAdd(item: T): void {
        if (item.destroyed) {
            console.warn("不能添加被删除的对象", item);
            return;
        }
        this.delayAddList.push(item);
        this.m_AddDirty = true;
    }

    DelayRemove(item: T) {
        item.destroyed = true;
        this.m_RemoveDirty = true;
    }

    ApplyDelayCommands() {
        if (this.m_RemoveDirty) {
            let count: number = this.length;
            // 空位位置，空位后的有效数据位置
            let i = 0, j = 0;
            while (i < count) {
                // 找到第一个空位
                if (this[i].destroyed) {
                    j = i + 1;
                    while (j < count) {
                        // 找到一个有效数据
                        if (!this[j].destroyed) {
                            // 把有效数据放到空位（可以理解为交换
                            this[i] = this[j];
                            i++; // 这个精髓了，无论如何i+1过后都是视为空位
                        }
                        j++;
                    }
                    this.splice(i);// 删除尾部空位（其实有数据，但是不要了
                    break;
                }
                i++;
            }
            this.m_RemoveDirty = false;
        }

        if (this.m_AddDirty) {
            this.push(...this.delayAddList);
            this.delayAddList = new Array();
            this.m_AddDirty = false;
        }
    }
}

// class test extends DItem {
//     value = Math.random().toFixed(4);
// }
// let a = new DList();
// const q1 = new test();
// const q2 = new test();
// const q3 = new test();
// const q4 = new test();
// const q5 = new test();
// a.push(q1, q2, q3, q4, q5);
// a.DelayRemove(q2);
// a.DelayRemove(q4);
// a.DelayAdd(q2);
// console.log(a);
// a.ApplyDelayCommands();
// console.log(a);
